<template>
  <div class="test-exam">
    <div style="height: 40px">
      <el-breadcrumb separator="/">
        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
        <el-breadcrumb-item>测试中</el-breadcrumb-item>
      </el-breadcrumb>
    </div>
    <!-- 提示框 -->
    <el-dialog
      title="考前提示"
      :visible.sync="dialogVisible"
      width="30%"
      :before-close="handleClose"
      :close-on-click-modal="false"
    >
      <div class="tips">
        <h3>沉着、冷静、细致、认真!</h3>
        <p>
          考试将在倒计时结束后进行开始，若暂无法考试，可在倒计时结束后推出考试系统；若以准备好可点击开始进行考试。
        </p>
        <p>
          考试时长：<span>{{ examTime }}</span
          >分钟
        </p>
        <p v-show="WaitForConfirmation">倒计时：</p>
        <div class="count-down" v-show="WaitForConfirmation">
          {{ countDownTime }}
        </div>
      </div>
      <span slot="footer" class="dialog-footer" v-show="!WaitForConfirmation">
        <el-button @click="cancel" :disabled="WaitForConfirmation"
          >取 消</el-button
        >
        <el-button
          type="primary"
          @click="confirm"
          :disabled="WaitForConfirmation"
          >开 始</el-button
        >
      </span>
    </el-dialog>
    <!-- 考试题目 -->
    <div class="topic" v-loading="examLoading">
      <el-card v-if="currentQuestion">
        <div class="header">
          <div style="width: 500px">
            <h2>测试中</h2>
            <p>已完成/总题量-{{ answers.length }}/{{ questions.length }}</p>
          </div>
          <div>
            <div class="title">
              <span>考试时间：{{ examTime }}分钟</span>
            </div>
            <div class="count-down">
              <span>倒计时：</span>
              <span>{{ hours }}:{{ minutes }}:{{ seconds }}</span>
            </div>
          </div>
        </div>
        <h3>
          {{ currentIndex + 1 }}.
          <span v-html="currentQuestion.topicName"></span>（{{
            currentQuestion.topicScore
          }}分）
        </h3>
        <el-radio-group v-model="selectedOption" style="margin-top: 20px">
          <el-radio label="A">
            A、<span v-html="currentQuestion.topicOptionA"></span
          ></el-radio>
          <el-radio label="B">
            B、<span v-html="currentQuestion.topicOptionB"></span
          ></el-radio>
          <el-radio label="C">
            C、<span v-html="currentQuestion.topicOptionC"></span
          ></el-radio>
          <el-radio label="D">
            D、<span v-html="currentQuestion.topicOptionD"></span
          ></el-radio>
        </el-radio-group>
        <div class="buttons">
          <span v-show="answers[currentIndex]"
            >你的选项为：{{
              answers.length > 0 && currentIndex !== answers.length
                ? answers[currentIndex].topicUserOption
                : ""
            }}</span
          >
          <el-button
            type="primary"
            @click="prevQuestion"
            :disabled="currentIndex === 0"
            size="mini"
            >上一题</el-button
          >
          <el-button
            type="primary"
            @click="nextQuestion"
            :disabled="!selectedOption"
            size="mini"
            >{{
              questions.length !== answers.length ? "下一题" : "修改"
            }}</el-button
          >
          <el-button
            type="success"
            @click="submitAnswers"
            :disabled="questions.length !== answers.length"
            size="mini"
            :loading="submitLoding"
            >提交</el-button
          >
        </div>
      </el-card>
    </div>
    <!-- 超时提示框 -->
    <el-dialog
      :visible.sync="overTimeDialogVisible"
      width="30%"
      :before-close="handleClose"
      :close-on-click-modal="false"
    >
      <div class="tips">
        <h3>考试时间已结束，停止作答，5秒后将自动交卷。</h3>
        <div class="count-down">{{ overTimeCountDown }}</div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { insertTestExamRecord } from "@/api/client/exam";
import { getExamTopicAll } from "@/api/client/testExamTopic";
import { MessageBox } from "element-ui";

export default {
  name: "testExamView",
  props: ["testExamId", "examTime", "testExamName", "testCategoryId"],
  data() {
    return {
      dialogVisible: true,
      overTimeDialogVisible: false,
      // 倒计时
      countDownTime: 5,
      // 超时倒计时
      overTimeCountDown: 5,
      // 等待倒计时
      WaitForConfirmation: true,
      // 考试计时器
      examTimer: null,
      // 全部题目数组
      questions: [],
      // 当前题目索引
      currentIndex: 0,
      // 用户选项数组
      answers: [],
      // 用户选项
      selectedOption: "",
      examLoading: false,
      submitLoding: false,
      // 考试时间
      totalSeconds: this.examTime * 60,
      hours: 0,
      minutes: 0,
      seconds: 0,
      // 所用时间
      usedTime: 0,
      usedTimeStr: "",
    };
  },
  created() {
    this.countDown();
  },
  computed: {
    currentQuestion() {
      // 移出this.questions中的topicRightOption属性
      if (this.questions.length > 0) {
        const { topicRightOption, ...rest } = this.questions[this.currentIndex];
        return rest;
      }
    },
  },
  methods: {
    // 进场倒计时
    countDown() {
      let timer = setInterval(() => {
        this.countDownTime--;
        if (this.countDownTime <= 0) {
          clearInterval(timer);
          this.WaitForConfirmation = false;
        }
      }, 1000);
    },
    // 超时对话框倒计时
    overTime() {
      let timer = setInterval(() => {
        this.overTimeCountDown--;
        if (this.overTimeCountDown <= 0) {
          clearInterval(timer);
          // 倒计时结束后进行自动提交
          this.submitAnswers();
        }
      }, 1000);
    },
    // 测试时间倒计时
    examCountDown() {
      // 将总秒数转换为小时、分钟和秒
      this.hours = Math.floor(this.totalSeconds / 3600);
      this.minutes = Math.floor((this.totalSeconds % 3600) / 60);
      this.seconds = this.totalSeconds % 60;
      // 每秒更新倒计时
      this.examTimer = setInterval(() => {
        if (this.totalSeconds > 0) {
          this.totalSeconds--;
          this.hours = Math.floor(this.totalSeconds / 3600);
          this.minutes = Math.floor((this.totalSeconds % 3600) / 60);
          this.seconds = this.totalSeconds % 60;
          this.usedTime++;
        } else {
          // 倒计时结束
          clearInterval(this.examTimer);
          this.formatTime();
          this.overTimeDialogVisible = true;
          this.overTime();
        }
      }, 1000);
    },
    // 时间格式转换
    formatTime() {
      // 秒数转换成时分秒
      const usedHours = Math.floor(this.usedTime / 3600);
      const usedMinutes = Math.floor((this.usedTime % 3600) / 60);
      const usedSeconds = this.usedTime % 60;
      this.usedTimeStr = `${usedHours}时${usedMinutes}分${usedSeconds}秒`;
    },
    // 取消
    cancel() {
      this.dialogVisible = false;
      this.$router.push({ path: "/testQuestion" });
    },
    // 点击对话框的关闭按钮
    handleClose() {
      MessageBox.confirm("确定要退出考试吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        this.$router.push(`/testQuestion`);
      });
    },
    // 确定
    confirm() {
      this.dialogVisible = false;
      this.getExamTopic();
      this.examCountDown();
    },
    // 获取题目
    async getExamTopic() {
      try {
        this.examLoading = true;
        const res = await getExamTopicAll({
          testExamId: this.testExamId,
        });
        this.questions = res.data;
      } finally {
        this.examLoading = false;
      }
    },
    // 下一题
    nextQuestion() {
      if (this.selectedOption) {
        if (this.currentIndex < this.answers.length) {
          // 如果索引小于答案数组长度，则替换答案数组中的答案
          this.answers[this.currentIndex].topicUserOption = this.selectedOption;
        } else {
          // 如果索引大于等于答案数组长度，则向答案数组中添加答案
          // 当前题目id
          const currentId = this.questions[this.currentIndex].id;
          // 当前题目名称
          const currentTopicName = this.questions[this.currentIndex].topicName;
          this.answers.push({
            id: currentId,
            testExamId: this.testExamId,
            topicName: currentTopicName,
            topicUserOption: this.selectedOption,
          });
        }
        // 将当前选项置空
        this.selectedOption = "";
        if (this.currentIndex < this.questions.length - 1) {
          // 如果当前题目数组下标小于数组长度，则进入下一题
          this.currentIndex++;
        } else {
          this.$message.warning("已经是最后一题了");
        }
      } else {
        this.$message.warning("请选择一个选项");
      }
    },
    // 上一题
    prevQuestion() {
      if (this.currentIndex > 0) {
        this.currentIndex--;
        // 将选项置空
        this.selectedOption = "";
      } else {
        alert("已经是第一题了！");
      }
    },
    // 提交答案
    async submitAnswers() {
      try {
        this.submitLoding = true;
        // 手动关闭setInterval，并获取考试用时
        clearInterval(this.examTimer);
        this.formatTime();
        // 若answer数组中的答案只有一部分，把剩下的通过和questions数组中的题目做对比后补全
        if (this.answers.length < this.questions.length) {
          this.answers = this.questions.map((item) => {
            const answer = this.answers.find((answer) => answer.id === item.id);
            return answer
              ? answer
              : {
                  id: item.id,
                  testExamId: this.testExamId,
                  topicName: item.topicName,
                  topicUserOption: "",
                };
          });
        }
        const res = await insertTestExamRecord({
          testCategoryId: this.testCategoryId,
          testExamName: this.testExamName,
          spentTime: this.usedTimeStr,
          testExamTopicList: this.answers,
        });
        this.$router.push("/testQuestion");
      } finally {
        this.submitLoding = false;
      }
    },
  },
};
</script>

<style lang="less" scoped>
.test-exam {
  width: 100%;
  height: 90vh;
  padding: 10px 60px;
  background-color: #fff;
  .tips {
    h3 {
      text-align: center;
    }
    p {
      margin-top: 10px;
      line-height: 2;
      text-indent: 2em;
      span {
        font-weight: 600;
        font-size: 17px;
        color: red;
      }
    }
    .count-down {
      margin: 10px auto;
      width: 60px;
      height: 60px;
      font-size: 26px;
      text-align: center;
      line-height: 60px;
      color: rgb(247, 15, 15);
      border-radius: 50%;
      border: 2px solid rgb(247, 15, 15);
    }
  }
  .topic {
    .header {
      display: flex;
      justify-content: space-between;
      margin-bottom: 20px;
      h2,
      p {
        display: inline-block;
      }
      p {
        margin-left: 20px;
      }
      span {
        font-weight: 600;
      }
      .title {
        width: 132px;
        text-align: left;
      }
      .count-down {
        margin-top: 4px;
        width: 132px;
        text-align: left;
      }
    }
    .buttons {
      margin-top: 20px;
      display: flex;
      justify-content: flex-end;
      align-items: flex-end;
      span {
        margin-right: 12px;
      }
    }
  }
}
/* 解决浏览器报错：Blocked aria-hidden on an element because its descendant retained focus */
/deep/input[aria-hidden="true"] {
  display: none !important;
}
</style>